package service

import (
	"encoding/json"
	"errors"
	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/repository"
	"time"
)

// ReviewService 评价服务接口
type ReviewService interface {
	// 课程评价管理
	CreateCourseReview(userID uint, req *model.CreateCourseReviewReq) error
	GetCourseReviews(courseID uint, req *model.CourseReviewListReq, currentUserID uint) (*model.CourseReviewListResp, error)
	MarkReviewHelpful(userID, reviewID uint) error
	UnmarkReviewHelpful(userID, reviewID uint) error
	ReplyToReview(userID uint, userType string, reviewID uint, reviewType, content string) error

	// 教练评分管理
	CreateCoachRating(userID uint, req *model.CreateCoachRatingReq) (*model.CoachRatingResp, error)
	GetCoachRatings(coachID uint, req *model.CoachRatingListReq) (*model.CoachRatingListResp, error)

	// 意见反馈管理
	CreateFeedback(userID uint, req *model.CreateFeedbackReq) error
	GetMyFeedbacks(userID uint) ([]model.Feedback, error)
	GetAllFeedbacks(req *model.FeedbackListReq) (*model.FeedbackListResp, error)
	HandleFeedback(handlerID, feedbackID uint, req *model.HandleFeedbackReq) error

	// 管理员功能
	AuditReview(adminID, reviewID uint, req *model.AuditReviewReq) error
	FeatureReview(adminID, reviewID uint, req *model.FeatureReviewReq) error
	HideReview(adminID, reviewID uint) error

	// 评价举报管理
	ReportReview(userID uint, req *model.ReportReviewReq) error
	GetReviewReports(req *model.ReviewReportListReq) (*model.ReviewReportListResp, error)
	HandleReviewReport(adminID, reportID uint, req *model.HandleReportReq) error
}

type reviewService struct {
	repo repository.ReviewRepository
}

func NewReviewService(repo repository.ReviewRepository) ReviewService {
	return &reviewService{repo: repo}
}

// ==================== 课程评价管理 ====================

func (s *reviewService) CreateCourseReview(userID uint, req *model.CreateCourseReviewReq) error {
	// 检查是否已经评价过该课程
	// TODO: 实现检查逻辑，确保每个用户只能对同一预约评价一次

	// 转换图片和标签为JSON字符串
	var imagesJSON, tagsJSON string
	if len(req.Images) > 0 {
		if imagesBytes, err := json.Marshal(req.Images); err == nil {
			imagesJSON = string(imagesBytes)
		}
	}
	if len(req.Tags) > 0 {
		if tagsBytes, err := json.Marshal(req.Tags); err == nil {
			tagsJSON = string(tagsBytes)
		}
	}

	review := &model.CourseReview{
		CourseID:    req.CourseID,
		UserID:      userID,
		Rating:      req.Rating,
		Content:     req.Content,
		Images:      imagesJSON,
		Tags:        tagsJSON,
		IsAnonymous: req.IsAnonymous,
		Status:      "PENDING", // 默认需要审核
	}

	return s.repo.CreateCourseReview(review)
}

func (s *reviewService) GetCourseReviews(courseID uint, req *model.CourseReviewListReq, currentUserID uint) (*model.CourseReviewListResp, error) {
	reviews, total, err := s.repo.GetCourseReviewsByCourseID(courseID, req)
	if err != nil {
		return nil, err
	}

	// 获取评分统计信息
	ratingDistribution, avgRating, err := s.repo.GetCourseReviewSummary(courseID)
	if err != nil {
		return nil, err
	}

	// 转换为详情列表
	var reviewDetails []model.CourseReviewDetail
	for _, review := range reviews {
		// 解析图片和标签
		var images []string
		var tags []string
		if review.Images != "" {
			json.Unmarshal([]byte(review.Images), &images)
		}
		if review.Tags != "" {
			json.Unmarshal([]byte(review.Tags), &tags)
		}

		// 获取用户信息（匿名评价不显示用户信息）
		userInfo := model.UserInfo{}
		if !review.IsAnonymous {
			if review.User != nil {
				userInfo.ID = review.User.ID
				userInfo.Username = review.User.Username
				// userInfo.Avatar = review.User.Avatar // 如果用户表有头像字段
			}
		} else {
			userInfo.Username = "匿名用户"
		}

		// 检查当前用户是否标记为有用
		isHelpful := false
		if currentUserID > 0 {
			if _, err := s.repo.GetUserHelpfulReview(currentUserID, review.ID); err == nil {
				isHelpful = true
			}
		}

		// 获取回复
		replies, _ := s.repo.GetReviewReplies(review.ID, "COURSE")

		reviewDetails = append(reviewDetails, model.CourseReviewDetail{
			ID:           review.ID,
			User:         userInfo,
			Rating:       review.Rating,
			Content:      review.Content,
			Images:       images,
			Tags:         tags,
			HelpfulCount: review.HelpfulCount,
			IsHelpful:    isHelpful,
			Replies:      replies,
			CreatedAt:    review.CreatedAt,
		})
	}

	resp := &model.CourseReviewListResp{
		List:  reviewDetails,
		Total: total,
		Page:  req.Page,
		Size:  req.PageSize,
	}
	resp.Summary.TotalCount = int(total)
	resp.Summary.AvgRating = avgRating
	resp.Summary.RatingDistribution = ratingDistribution

	return resp, nil
}

func (s *reviewService) MarkReviewHelpful(userID, reviewID uint) error {
	// 检查是否已经标记过
	if _, err := s.repo.GetUserHelpfulReview(userID, reviewID); err == nil {
		return errors.New("已经标记为有用")
	}

	helpful := &model.ReviewHelpful{
		ReviewID:  reviewID,
		UserID:    userID,
		CreatedAt: time.Now(),
	}

	if err := s.repo.CreateReviewHelpful(helpful); err != nil {
		return err
	}

	// 更新评价的有用数
	review, err := s.repo.GetCourseReviewByID(reviewID)
	if err != nil {
		return err
	}
	review.HelpfulCount++
	return s.repo.UpdateCourseReview(review)
}

func (s *reviewService) UnmarkReviewHelpful(userID, reviewID uint) error {
	// 检查是否已经标记过
	helpful, err := s.repo.GetUserHelpfulReview(userID, reviewID)
	if err != nil {
		return errors.New("尚未标记为有用")
	}

	if err := s.repo.DeleteReviewHelpful(helpful.ID); err != nil {
		return err
	}

	// 更新评价的有用数
	review, err := s.repo.GetCourseReviewByID(reviewID)
	if err != nil {
		return err
	}
	if review.HelpfulCount > 0 {
		review.HelpfulCount--
	}
	return s.repo.UpdateCourseReview(review)
}

func (s *reviewService) ReplyToReview(userID uint, userType string, reviewID uint, reviewType, content string) error {
	reply := &model.ReviewReply{
		ReviewID:   reviewID,
		ReviewType: reviewType,
		UserID:     userID,
		UserType:   userType,
		Content:    content,
		IsOfficial: userType == "ADMIN" || userType == "COACH",
		CreatedAt:  time.Now(),
		UpdatedAt:  time.Now(),
	}

	return s.repo.CreateReviewReply(reply)
}

// ==================== 教练评分管理 ====================

func (s *reviewService) CreateCoachRating(userID uint, req *model.CreateCoachRatingReq) (*model.CoachRatingResp, error) {
	rating := &model.CoachRating{
		CoachID:         req.CoachID,
		UserID:          userID,
		BookingID:       req.BookingID,
		OverallRating:   req.OverallRating,
		Professionalism: req.Professionalism,
		Patience:        req.Patience,
		Enthusiasm:      req.Enthusiasm,
		Communication:   req.Communication,
		Content:         req.Content,
		IsAnonymous:     req.IsAnonymous,
		CreatedAt:       time.Now(),
		UpdatedAt:       time.Now(),
	}

	if err := s.repo.CreateCoachRating(rating); err != nil {
		return nil, err
	}

	return &model.CoachRatingResp{
		ID:            rating.ID,
		OverallRating: rating.OverallRating,
	}, nil
}

func (s *reviewService) GetCoachRatings(coachID uint, req *model.CoachRatingListReq) (*model.CoachRatingListResp, error) {
	ratings, total, err := s.repo.GetCoachRatingsByCoachID(coachID, req)
	if err != nil {
		return nil, err
	}

	// 获取评分统计信息
	avgOverall, avgProfessionalism, avgPatience, avgEnthusiasm, avgCommunication, totalCount, err := s.repo.GetCoachRatingSummary(coachID)
	if err != nil {
		return nil, err
	}

	// 转换为详情列表
	var ratingDetails []model.CoachRatingDetail
	for _, rating := range ratings {
		// 获取用户信息（匿名评价不显示用户信息）
		userInfo := model.UserInfo{}
		if !rating.IsAnonymous {
			if rating.User != nil {
				userInfo.ID = rating.User.ID
				userInfo.Username = rating.User.Username
				// userInfo.Avatar = rating.User.Avatar // 如果用户表有头像字段
			}
		} else {
			userInfo.Username = "匿名用户"
		}

		ratingDetails = append(ratingDetails, model.CoachRatingDetail{
			ID:            rating.ID,
			User:          userInfo,
			OverallRating: rating.OverallRating,
			Content:       rating.Content,
			CreatedAt:     rating.CreatedAt,
		})
	}

	resp := &model.CoachRatingListResp{
		List:  ratingDetails,
		Total: total,
	}
	resp.Summary.TotalCount = totalCount
	resp.Summary.AvgOverallRating = avgOverall
	resp.Summary.AvgProfessionalism = avgProfessionalism
	resp.Summary.AvgPatience = avgPatience
	resp.Summary.AvgEnthusiasm = avgEnthusiasm
	resp.Summary.AvgCommunication = avgCommunication

	return resp, nil
}

// ==================== 意见反馈管理 ====================

func (s *reviewService) CreateFeedback(userID uint, req *model.CreateFeedbackReq) error {
	// 转换图片为JSON字符串
	var imagesJSON string
	if len(req.Images) > 0 {
		if imagesBytes, err := json.Marshal(req.Images); err == nil {
			imagesJSON = string(imagesBytes)
		}
	}

	feedback := &model.Feedback{
		UserID:       userID,
		Type:         req.Type,
		Category:     req.Category,
		Title:        req.Title,
		Content:      req.Content,
		Images:       imagesJSON,
		ContactPhone: req.ContactPhone,
		ContactEmail: req.ContactEmail,
		Priority:     s.determineFeedbackPriority(req.Content, req.Type),
		Status:       "PENDING",
		CreatedAt:    time.Now(),
		UpdatedAt:    time.Now(),
	}

	return s.repo.CreateFeedback(feedback)
}

func (s *reviewService) determineFeedbackPriority(content, feedbackType string) string {
	// 根据内容和类型自动判断优先级
	if feedbackType == "COMPLAINT" {
		return "HIGH"
	}

	// 检查是否包含紧急关键词
	urgentKeywords := []string{"紧急", "严重", "立即", "马上", "故障"}
	for _, keyword := range urgentKeywords {
		if len(content) >= len(keyword) {
			for i := 0; i <= len(content)-len(keyword); i++ {
				if content[i:i+len(keyword)] == keyword {
					return "HIGH"
				}
			}
		}
	}

	return "NORMAL"
}

func (s *reviewService) GetMyFeedbacks(userID uint) ([]model.Feedback, error) {
	return s.repo.GetUserFeedbacks(userID)
}

func (s *reviewService) GetAllFeedbacks(req *model.FeedbackListReq) (*model.FeedbackListResp, error) {
	feedbacks, total, err := s.repo.GetFeedbacks(req)
	if err != nil {
		return nil, err
	}

	return &model.FeedbackListResp{
		List:  feedbacks,
		Total: total,
		Page:  req.Page,
		Size:  req.PageSize,
	}, nil
}

func (s *reviewService) HandleFeedback(handlerID, feedbackID uint, req *model.HandleFeedbackReq) error {
	feedback, err := s.repo.GetFeedbackByID(feedbackID)
	if err != nil {
		return errors.New("反馈不存在")
	}

	feedback.Status = req.Status
	feedback.Reply = req.Reply
	feedback.HandlerID = &handlerID
	if req.Status == "RESOLVED" {
		now := time.Now()
		feedback.ResolvedAt = &now
	}
	feedback.UpdatedAt = time.Now()

	return s.repo.UpdateFeedback(feedback)
}

// ==================== 管理员功能 ====================

func (s *reviewService) AuditReview(adminID, reviewID uint, req *model.AuditReviewReq) error {
	review, err := s.repo.GetCourseReviewByID(reviewID)
	if err != nil {
		return errors.New("评价不存在")
	}

	review.Status = req.Status
	if req.Status == "REJECTED" {
		review.RejectReason = req.RejectReason
	}
	review.UpdatedAt = time.Now()

	return s.repo.UpdateCourseReview(review)
}

func (s *reviewService) FeatureReview(adminID, reviewID uint, req *model.FeatureReviewReq) error {
	review, err := s.repo.GetCourseReviewByID(reviewID)
	if err != nil {
		return errors.New("评价不存在")
	}

	review.IsFeatured = req.IsFeatured
	review.UpdatedAt = time.Now()

	return s.repo.UpdateCourseReview(review)
}

func (s *reviewService) HideReview(adminID, reviewID uint) error {
	review, err := s.repo.GetCourseReviewByID(reviewID)
	if err != nil {
		return errors.New("评价不存在")
	}

	review.Status = "HIDDEN"
	review.UpdatedAt = time.Now()

	return s.repo.UpdateCourseReview(review)
}

// ==================== 评价举报管理 ====================

func (s *reviewService) ReportReview(userID uint, req *model.ReportReviewReq) error {
	report := &model.ReviewReport{
		ReviewID:    req.ReviewID,
		UserID:      userID,
		Reason:      req.Reason,
		Description: req.Description,
		Status:      "PENDING",
		CreatedAt:   time.Now(),
		UpdatedAt:   time.Now(),
	}

	return s.repo.CreateReviewReport(report)
}

func (s *reviewService) GetReviewReports(req *model.ReviewReportListReq) (*model.ReviewReportListResp, error) {
	reports, total, err := s.repo.GetReviewReports(req)
	if err != nil {
		return nil, err
	}

	return &model.ReviewReportListResp{
		List:  reports,
		Total: total,
		Page:  req.Page,
		Size:  req.PageSize,
	}, nil
}

func (s *reviewService) HandleReviewReport(adminID, reportID uint, req *model.HandleReportReq) error {
	report, err := s.repo.GetReviewReportByID(reportID)
	if err != nil {
		return errors.New("举报记录不存在")
	}

	report.Status = req.Status
	report.HandlerID = &adminID
	now := time.Now()
	report.HandledAt = &now
	report.UpdatedAt = now

	// 如果需要处理关联的评价
	if req.Action != "" {
		review, err := s.repo.GetCourseReviewByID(report.ReviewID)
		if err != nil {
			return errors.New("关联的评价不存在")
		}

		switch req.Action {
		case "HIDE":
			review.Status = "HIDDEN"
		case "DELETE":
			// 删除评价
			if err := s.repo.DeleteCourseReview(review.ID); err != nil {
				return errors.New("删除评价失败: " + err.Error())
			}
		}

		if req.Action == "HIDE" {
			review.UpdatedAt = now
			if err := s.repo.UpdateCourseReview(review); err != nil {
				return errors.New("更新评价状态失败: " + err.Error())
			}
		}
	}

	return s.repo.UpdateReviewReport(report)
}
